<?php
// +----------------------------------------------------------------------
// | 消息中间件
// +----------------------------------------------------------------------
// | 处理发送消息
// +----------------------------------------------------------------------
// | 错误编码头 201xxx
// +----------------------------------------------------------------------
namespace support\middleware;


use support\ErrorCode;
use think\module\Module;
use think\Request;
use think\Response;
use common\service\LoginService;

class RequestCheck
{
    protected $loginService;

    // 请求参数
    protected $param;

    public function __construct()
    {
        $this->loginService = LoginService::getInstance();
    }

    /**
     * @param Request $request
     * @param callable $next
     * @return Response
     * @throws \Exception
     */
    public function process(Request $request, callable $next): Response
    {
        // 从header头获取token
        $XUserInfoBase64 = $request->header('x-userinfo');

        APP_DEBUG && trace('REQUEST X-USERINFO: ' . $XUserInfoBase64, 'DEBUG');
        // 请求参数
        $this->param = $request->param();

        if (empty($XUserInfoBase64)) {
            // 错误的header头参数
            APP_DEBUG && trace("Wrong header param.", "DEBUG");
            throw_strack_exception("Wrong header param.", ErrorCode::WRONG_HEADER_PARAM);
        }

        $XUserInfoBase = json_decode(base64_decode($XUserInfoBase64), true);

        if (!empty($XUserInfoBase) && !empty($XUserInfoBase['id'])) {
            if (empty($XUserInfoBase['tenant_id'])) {
                throw_strack_exception("missing tenant", ErrorCode::MISSING_TENANT);
            }
            $userDataIn = [
                'phone' => $XUserInfoBase['phone'],
                'email' => $XUserInfoBase['email'],
                'name' => $XUserInfoBase['name'],
                'union_id' => $XUserInfoBase['id'],
                'avatar' => !empty($XUserInfoBase['avatar']) ? $XUserInfoBase['avatar'] : "",
            ];

            $userCache = $request->getUserInfoCache($XUserInfoBase['id'], $userDataIn);

            if ($userCache !== false) {
                $userData = $userCache;
            } else {
                // 同步用户信息
                $userData = $this->loginService->syncUserBasicData($XUserInfoBase);
                $request->setUserInfoCache($XUserInfoBase['id'], $userData);
            }


            // 初始化项目ID
            $projectId = array_key_exists('project_id', $this->param) ? $this->param['project_id'] : 0;


            // 设置当前module code
            $currentModuleCode = $this->getCurrentModuleCode($request);

            $request->getModuleCode($currentModuleCode);
            $request->getProjectId($projectId);
            $request->getTenantId($XUserInfoBase['tenant_id']);
            $request->getUserUUID($userData['uuid']);
            $request->getUserId($userData['id']);
            $request->getUnionUserId($XUserInfoBase['id']);
            $request->getXUserInfo($XUserInfoBase64);

            // 生成当前请求批次号
            $batchNumber = C('belong_system') . '_' . string_random(8) . '-' . create_uuid();
            $request->getBatchNumber($batchNumber);
        } else {
            // 错误的header头参数
            APP_DEBUG && trace("Wrong user info param.", "DEBUG");
            throw_strack_exception("Wrong user info param.", ErrorCode::WRONG_USER_INFO_PARAM);
        }

        return $next($request);
    }

    /**
     * 获取当前模块编码
     * @param Request $request
     * @return string
     */
    protected function getCurrentModuleCode(Request $request)
    {
        $controller = to_under_score($request->controller());

        if ($controller === 'entity') {
            if (!array_key_exists('module_code', $this->param)) {
                throw_strack_exception('Module parameter does not exist.', ErrorCode::MODULE_PARAM_NOT_EXIST);
            }

            $currentModuleCode = $this->param['module_code'];

            if (!array_key_exists($currentModuleCode, Module::$moduleDictData['module_index_by_code'])) {
                throw_strack_exception('Current module does not exist.', ErrorCode::MODULE_NOT_EXIST);
            }

        } else {
            if (array_key_exists('module_code', $this->param)) {
                $currentModuleCode = $this->param['module_code'];
            } else {
                $currentModuleCode = $controller;
            }
        }

        return $currentModuleCode;
    }
}
